﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assets.Scripts.GtsScripts;
using Assets.Scripts.ProceduralCityGenerator;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Jobs;

// Token: 0x02000332 RID: 818
internal class ActorPopulationManager
{
	// Token: 0x0600151F RID: 5407 RVA: 0x000897FC File Offset: 0x000879FC
	private ActorPopulationManager(CityPopulationManager parent)
	{
		this.Parent = parent;
		this.ActiveMicros = new List<Micro>();
		this.State = false;
		this.Enable = true;
	}

	// Token: 0x06001520 RID: 5408 RVA: 0x0008984A File Offset: 0x00087A4A
	public ActorPopulationManager(CityPopulationManager parent, Player player) : this(parent)
	{
		this.Actor = player;
		this.SpawnDistance = 100f * parent.CityScale;
	}

	// Token: 0x06001521 RID: 5409 RVA: 0x0008986C File Offset: 0x00087A6C
	public ActorPopulationManager(CityPopulationManager parent, Giantess gts) : this(parent)
	{
		this.SpawnDistance = 300f * parent.CityScale;
		this.Actor = gts;
	}

	// Token: 0x06001522 RID: 5410 RVA: 0x00089890 File Offset: 0x00087A90
	public bool ActorUpdate(int ActorCount, int MicroCount)
	{
		if (this.RunningThread)
		{
			this.TeleportClean();
		}
		if (!this.Enable || this.Actor == null)
		{
			return false;
		}
		this.ActiveMicros.RemoveAll((Micro x) => x == null);
		if (this.State && MicroCount < this.cMaxMicros)
		{
			this.State = this.SpawnMicros(ActorCount, MicroCount);
			if (this.State && MicroCount < Mathf.Min(this.cMaxMicros, 15))
			{
				this.CheckMicroStatus(true);
			}
		}
		else
		{
			this.CheckMicroStatus(false);
			if (MicroCount < this.cMaxMicros)
			{
				this.State = true;
			}
		}
		return this.State;
	}

	// Token: 0x06001523 RID: 5411 RVA: 0x00089964 File Offset: 0x00087B64
	public void Destroy()
	{
		if (this.RunningThread)
		{
			this.TeleportClean();
		}
		foreach (Micro micro in this.ActiveMicros)
		{
			micro.ForceDestroy(true);
		}
		this.ActiveMicros.Clear();
	}

	// Token: 0x06001524 RID: 5412 RVA: 0x000899DC File Offset: 0x00087BDC
	private void TeleportClean()
	{
		this.m_TeleportJobHandle.Complete();
		this.m_dest.Dispose();
		this.m_TransformsAccessArray.Dispose();
		this.RunningThread = false;
	}

	// Token: 0x06001525 RID: 5413 RVA: 0x00089A08 File Offset: 0x00087C08
	private void CheckMicroStatus(bool close = false)
	{
		this.v2a.x = this.Actor.GetHumonoidPosition().x;
		this.v2a.y = this.Actor.GetHumonoidPosition().z;
		this.GetSpawnBuildingsInRange();
		int num = (!close) ? 10 : 1;
		if (this.buildingOptions.Count < num)
		{
			this.buildingOptions.Clear();
			return;
		}
		IList<Micro> list = (from x in this.ActiveMicros
		where Vector2.Distance(new Vector2(x.transform.position.x, x.transform.position.z), this.v2a) > this.SpawnDistance * this.Parent.CityScale * 1.2f
		select x).ToList<Micro>();
		if (list.Count < 1)
		{
			list.Clear();
			return;
		}
		this.m_dest = new NativeArray<Vector3>(list.Count, Allocator.Persistent, NativeArrayOptions.ClearMemory);
		Transform[] array = new Transform[list.Count];
		for (int i = 0; i < list.Count; i++)
		{
			this.m_dest[i] = this.GetBuildingSpawnSpot(this.buildingOptions[UnityEngine.Random.Range(0, this.buildingOptions.Count)]);
			array[i] = list[i].transform;
		}
		this.m_TransformsAccessArray = new TransformAccessArray(array, -1);
		list.Clear();
		this.buildingOptions.Clear();
		ActorPopulationManager.TeleportMicro jobData = new ActorPopulationManager.TeleportMicro
		{
			destination = this.m_dest
		};
		this.m_TeleportJobHandle = jobData.Schedule(this.m_TransformsAccessArray, this.m_TeleportJobHandle);
		this.RunningThread = true;
	}

	// Token: 0x06001526 RID: 5414 RVA: 0x00089B88 File Offset: 0x00087D88
	private bool SpawnMicros(int actorCount, int MicroCount)
	{
		int num = (this.cMaxMicros - MicroCount) / actorCount;
		if (num > 0)
		{
			int num2 = (MicroCount != 0) ? Mathf.Min(1, num) : num;
			for (int i = 0; i < num2; i++)
			{
				Vector3 buildingSpawnSpot = this.GetBuildingSpawnSpot(this.Parent.Buildings[UnityEngine.Random.Range(0, this.Parent.Buildings.Count)]);
				buildingSpawnSpot.x += (float)i;
				Micro micro = this.SpawnMicro(buildingSpawnSpot);
				if (micro != null)
				{
					this.ActiveMicros.Add(micro);
				}
			}
			if (num - num2 < 1)
			{
				return false;
			}
		}
		return true;
	}

	// Token: 0x06001527 RID: 5415 RVA: 0x00089C3C File Offset: 0x00087E3C
	private void GetSpawnBuildingsInRange()
	{
		foreach (CityBuilding cityBuilding in this.Parent.Buildings)
		{
			this.v2b.x = cityBuilding.transform.position.x;
			this.v2b.y = cityBuilding.transform.position.z;
			float num = Vector2.Distance(this.v2b, this.v2a);
			if (num <= this.SpawnDistance)
			{
				this.buildingOptions.Add(cityBuilding);
			}
		}
	}

	// Token: 0x06001528 RID: 5416 RVA: 0x00089D00 File Offset: 0x00087F00
	private Vector3 GetBuildingSpawnSpot(CityBuilding target)
	{
		Vector3 result = target.CellArea[UnityEngine.Random.Range(0, 5)];
		result.y = target.gameObject.transform.position.y + 10f;
		return result;
	}

	// Token: 0x06001529 RID: 5417 RVA: 0x00089D4C File Offset: 0x00087F4C
	private Micro SpawnMicro(Vector3 position)
	{
		bool flag = UnityEngine.Random.Range(0, 2) == 1;
		MicroNPC microNPC;
		if (flag)
		{
			microNPC = NPCSpawner.Instance.SpawnFemaleNPC();
		}
		else
		{
			microNPC = NPCSpawner.Instance.SpawnMaleNPC();
		}
		if (microNPC == null)
		{
			return null;
		}
		GameObject gameObject = ObjectManager.Instance.InstantiateMicro(microNPC, position, Quaternion.AngleAxis(180f, Vector3.up), this.Parent.CityScale);
		gameObject = ClientPlayer.Instance.RegisterMicro(gameObject, flag);
		Micro component = gameObject.GetComponent<MicroNPC>();
		component._ChangeScale(this.Parent.CityScale);
		EventManager.SendEvent(new SpawnEvent(gameObject.GetComponent<EntityBase>()));
		return component;
	}

	// Token: 0x040017C9 RID: 6089
	private Humanoid Actor;

	// Token: 0x040017CA RID: 6090
	private float SpawnDistance;

	// Token: 0x040017CB RID: 6091
	public List<Micro> ActiveMicros;

	// Token: 0x040017CC RID: 6092
	private bool State;

	// Token: 0x040017CD RID: 6093
	private CityPopulationManager Parent;

	// Token: 0x040017CE RID: 6094
	private bool Enable;

	// Token: 0x040017CF RID: 6095
	private const float cSpawnDistancePlayer = 100f;

	// Token: 0x040017D0 RID: 6096
	private const float cSpawnDistanceGts = 300f;

	// Token: 0x040017D1 RID: 6097
	public int cMaxMicros = GlobalPreferences.CityPopulation.value;

	// Token: 0x040017D2 RID: 6098
	private const int cMaxSpawnPerCycle = 1;

	// Token: 0x040017D3 RID: 6099
	private Vector2 v2a;

	// Token: 0x040017D4 RID: 6100
	private Vector2 v2b;

	// Token: 0x040017D5 RID: 6101
	private List<CityBuilding> buildingOptions = new List<CityBuilding>();

	// Token: 0x040017D6 RID: 6102
	private JobHandle m_TeleportJobHandle;

	// Token: 0x040017D7 RID: 6103
	private bool RunningThread;

	// Token: 0x040017D8 RID: 6104
	private TransformAccessArray m_TransformsAccessArray;

	// Token: 0x040017D9 RID: 6105
	private NativeArray<Vector3> m_dest;

	// Token: 0x02000333 RID: 819
	private struct TeleportMicro : IJobParallelForTransform
	{
		// Token: 0x0600152C RID: 5420 RVA: 0x00089E4D File Offset: 0x0008804D
		public void Execute(int i, TransformAccess transform)
		{
			transform.position = this.destination[i];
		}

		// Token: 0x040017DB RID: 6107
		public NativeArray<Vector3> destination;
	}
}
